/**
 * 
 */
package jp.tkym.labs.util.csv;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import jp.tkym.labs.util.file.ReadLineEvent;
import jp.tkym.labs.util.file.ReadLineFire;
import jp.tkym.labs.util.file.ReadLineListener;

public class CsvBeanFactory<B>{
	private CsvBeanConverter<B> converter;
	private ReadLineFire fire;
	
	public CsvBeanFactory(Class<B> cls, InputStream csvIs, String... properties){
		converter = new CsvBeanConverter<B>(cls, properties);
		fire = new ReadLineFire(csvIs);
	}
	
	public CsvBeanConverter<B> getConverter(){
		return converter;
	}
	
	public List<B> create() throws Exception{
		CsvBeanStore store = new CsvBeanStore(converter);
		fire.addReadLineListener(store);
		fire.load();
		return store.list();
	}
	
	class CsvBeanStore implements ReadLineListener{
		private CsvBeanConverter<B> converter;
		private List<B> store = new ArrayList<B>();
		private boolean isAutoProperty = false;
		private CsvLineBuffer buffer = new CsvLineBuffer();
		private boolean isFirstLine;
		
		CsvBeanStore(CsvBeanConverter<B> converter){
			this.converter = converter;
			if(converter.getProperties() != null && converter.getProperties().length==0){
				isAutoProperty = true;
			}
			isFirstLine = true;
		}
		
		@Override
		public void onRead(ReadLineEvent event) throws Exception {
			buffer.addLine(event.getLine());
			if(buffer.isCompleted()){
				processRowData(buffer.readRow());
			}
		}
		
		private void processRowData(String[] arrays){
			if(isFirstLine){
				if(isAutoProperty)
					converter.setProperties(arrays);
				isFirstLine = false;
			}else{
				store.add(converter.bean(arrays));
			}
		}
		
		List<B> list(){
			return store;
		}
	}
}